var hx = require("hbuilderx");
var fs = require('fs')
const path = require("path");
const { log } = require("console");

// 引入主要的类
let CustomDocument = hx.CustomEditor.CustomDocument;
let CustomEditorProvider = hx.CustomEditor.CustomEditorProvider;
let CustomDocumentEditEvent = hx.CustomEditor.CustomDocumentEditEvent;
let jsonArr = []
let content = ''
let webViewPanelHandle

async function setView(webViewPanel, uri) {
	let url = 'https://caiwu.bctos.cn/schema2view/#/'
	// let url = 'http://localhost:8080/schema2view/#/'
	webViewPanel.webView.html = '<script type="text/javascript">window.location.href="' + url + '"</script>';
}

function initViewData(content, webViewPanel) {
	// console.log("同步读取 ", content)
	webViewPanel.webView.postMessage({
		command: "initData",
		content: content
	});
}

// 继承CustomDocument
class CatCustomDocument extends CustomDocument {
	constructor(uri) {
		super(uri)
	}
	dispose() {
		super.dispose();
	}
}

// 继承CustomEditorProvider，实现必要的方法
class CatCustomEditorProvider extends CustomEditorProvider {
	constructor(context) {
		super()
	}
	openCustomDocument(uri) {
		// 创建CustomDocument
		return Promise.resolve(new CatCustomDocument(uri));
	}
	resolveCustomEditor(document, webViewPanel) {
		webViewPanelHandle = webViewPanel
		hx.window.setStatusBarMessage('正在打开可视化编辑界面');
		// 关联CustomDocument与WebViewPanel
		setView(webViewPanel, document._uri);

		let provider = this;
		webViewPanel.webView.onDidReceiveMessage(function(msg) {
			// console.log('onDidReceiveMessage', msg)
			if (!msg)
				return;
			if (msg.command == 'save') {
				console.log('savesavesave=========');
				provider.saveCustomDocument(document)
			} else if (msg.command == 'close') {
				webViewPanel.dispose();
			} else if (msg.command == 'update') {
				jsonArr = msg.jsonArr
				// console.log('jsonArr in', jsonArr);
				provider.onDidChangeCustomDocument.fire(new CustomDocumentEditEvent(document))
			} else if (msg.command == 'init') {
				let file = decodeURIComponent(document._uri.slice(8))
				// 同步读取
				content = fs.readFileSync(file).toString()
				// console.log("同步读取 ", content)
				
				let reg =
					/("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(\/{2,}.*?(\r|\n|$))|(\/\*(\n|.)*?\*\/)/g;
				content = content.replace(reg, function(word) {
					return /^\/{2,}/.test(word) || /^\/\*/.test(word) ? "" : word;
				});
				// console.log("清除注释后 ", content)
				
				content = JSON.parse(content)
				
				initViewData(content, webViewPanel)

				hx.window.clearStatusBarMessage();
			}
		});
	}
	saveCustomDocument(document) {
		// 保存document
		console.log('saveCustomDocument in');
		let file = decodeURIComponent(document._uri.slice(8))
		// console.log('save file', file);
		let save = saveBefor()
		// console.log("待保存的内容 ", save)

		//保存JSON数据 JSON.stringify(student, null, 2);
		let jsonStr = JSON.stringify(save, null, 2).replace(/\\"/g, "")
		// console.log("JSON数据 ", jsonStr)

		//return true;
		//异步写入
		fs.writeFile(file, jsonStr, function(err) {});

		let targetFile = save.filePath
		console.log("targetFile ", targetFile)

		let save2 = JSON.parse(JSON.stringify(save))
		delete save2.filePath
		let jsonStr2 = JSON.stringify(save2, null, 2).replace(/\\"/g, "")
		fs.writeFile(targetFile, jsonStr2, function(err) {});
		return true;
	}
	saveCustomDocumentAs(document, destination) {
		console.log('saveCustomDocumentAs', document, destination);
		// document另存为至destination
		return true;
	}
}
//由编辑的数组转成保存文档需要的数组，去掉一些没有配置的选项，保证文档的简洁性
function saveBefor() {
	for (let r in content.permission) {
		content.permission[r] = false
	}
	for (let p of jsonArr.permission) {
		content.permission[p] = true
	}

	content.required = []
	let order = 0
	content.properties = {
		"_id": {
			"description": "ID，系统自动生成",
			"order": order
		}
	}
	for (let f of jsonArr.properties) {
		if (f.name == '_id') continue;

		if (typeof(f.bsonType) == 'undefined') f.bsonType = 'string'
		order += 1
		var field = {
			"bsonType": f.bsonType,
			"label": f.label,
			"errorMessage": {},
			"forceDefaultValue": {},
			"order": order
		}

		if (f.isRequired) {
			content.required.push(f.name)
			if (f.requiredError) field.errorMessage.required = f.requiredError
		}

		if (f.description) field.description = f.description

		if (f.enumType == 'tree' && f.collection) {
			field.enumType = f.enumType
			field.enum = {
				"collection": f.collection,
				"field": f.field,
				"where": f.where,
				"orderby": f.orderby,
			}
		} else if (f.enumType == 'db' && f.collection) {
			field.enum = {
				"collection": f.collection,
				"field": f.field,
				"where": f.where,
				"orderby": f.orderby,
			}
		} else if (f.enumType == 'array' && f.enum) {
			field.enum = JSON.parse(f.enum)
		}

		if (f.bsonType == 'file') {
			if (f.fileMediaType) field.fileMediaType = f.fileMediaType
			if (f.fileExtName) field.fileExtName = f.fileExtName
		}
		if (f.bsonType == 'int') {
			if (f.minimum > 0) field.minimum = f.minimum
			if (f.exclusiveMinimum) field.exclusiveMinimum = f.exclusiveMinimum
			if (f.exclusiveMinimum == false && f.minimum > 0 && f.minimumError) {
				field.errorMessage.minimum = f.minimumError
			}

			if (f.maximum > 0) field.maximum = f.maximum
			if (f.exclusiveMaximum) field.exclusiveMaximum = f.exclusiveMaximum
			if (f.exclusiveMaximum == false && f.maximum > 0 && f.maximumError) {
				field.errorMessage.maximum = f.maximumError
			}
		}
		if (f.bsonType == 'string' || f.bsonType == 'array') {
			if (f.minLength > 0) field.minLength = f.minLength
			if (f.maxLength > 0) field.maxLength = f.maxLength

			if (f.minLength > 0 && f.minLengthError) {
				field.errorMessage.minLength = f.minLengthError
			}
			if (f.maxLength > 0 && f.maxLengthError) {
				field.errorMessage.maxLength = f.maxLengthError
			}
		}
		if (f.trim != 'none' && f.bsonType == 'string') field.trim = f.trim


		if (f.forceDefaultValue) {
			field.forceDefaultValue = {
				"$env": f.forceDefaultValue
			}
		} else if (f.defaultValue) {
			field.defaultValue = f.defaultValue
		}
		if (f.group) field.group = f.group

		if (f.format) field.format = f.format
		if (f.formatError) field.errorMessage.format = f.formatError

		if (f.pattern) {
			field.pattern = f.pattern
			if (f.patternError) field.errorMessage.pattern = f.patternError
		}

		if (f.validateFunction) {
			field.validateFunction = f.validateFunction
			if (f.functionError) field.errorMessage.func = f.functionError
		}

		if (Object.keys(field.errorMessage).length == 0) {
			delete field.errorMessage
		}
		if (Object.keys(field.forceDefaultValue).length == 0) {
			delete field.forceDefaultValue
		}

		content.properties[f.name] = field
	}
	return content
}
//该方法将在插件激活的时候调用
function activate(context) {
	hx.window.registerCustomEditorProvider("extension.schema2view", new CatCustomEditorProvider({
		supportsMultipleEditorsPerDocument: true
	}));

	let onDidSaveTextDocumentEventDispose = hx.workspace.onDidSaveTextDocument(function(document) {
		// console.log('onDidSaveTextDocument', document);
		//判断是否是指定的schema文件
		if (document.fileName.indexOf('.schema.json') == -1 || document.uri.path.indexOf('/database/') == -1)
			return true;

		//判断是否存在可视化缓存文件
		let fileName = document.fileName.replace('schema.json', 'schema.bctos.json')
		let fullPath = path.join(__dirname, "temp", fileName)
		if (!fs.existsSync(fullPath)) return true;

		//判断是否为本项目的缓存文件
		let json = fs.readFileSync(fullPath, 'utf8')
		json = JSON.parse(json)
		if (document.uri.path.indexOf(json.filePath) == -1) return true;

		//同步更新可视化文件
		let save2 = fs.readFileSync(json.filePath, 'utf8')
		save2 = JSON.parse(save2)
		save2.filePath = json.filePath
		let jsonStr2 = JSON.stringify(save2, null, 2).replace(/\\"/g, "")
		fs.writeFile(fullPath, jsonStr2, (err) => {});

		//同步更新到可视化界面
		initViewData(save2, webViewPanelHandle)
	});

	let disposable = hx.commands.registerCommand('bctos.schema2view', () => {
		let activeEditor = hx.window.getActiveTextEditor();
		activeEditor.then(function(editor) {
			let filePath = editor.document.uri.path.slice(1)
			let fname = editor.document.fileName;
			let index = fname.lastIndexOf('\\')
			fname = fname.substr(index + 1)
					
			let getText = editor.document.getText()
			getText = getText.replace('"bsonType": ', '"filePath": "' + filePath + '","bsonType": ');

			let dir = path.join(__dirname, "temp")

			//自动清空关闭项目的缓存文件
			hx.workspace.getWorkspaceFolders().then(wsFolders => {
				let files = fs.readdirSync(dir)
				if (!files.length) return true;

				files.forEach(file => {
					let fullPath = path.join(dir, file)
					fs.readFile(fullPath, 'utf8', (err, data) => {
						let json = JSON.parse(data)
						let exist = false
						for (let f of wsFolders) {
							if (json.filePath.indexOf(f.uri.fsPath + '/') != -
								1) {
								exist = true;
								break;
							}
						}
						if (!exist) { //不存在当前开启的项目中的缓存文件，删除
							fs.unlink(fullPath, () => {})
						}
					})
				})
			});


			let f = path.join(dir, fname.replace('schema.json', 'schema.bctos.json'));
			fs.writeFileSync(f, getText);
			hx.workspace.openTextDocument(f);
		});
	});
	//订阅销毁钩子，插件禁用的时候，自动注销该command。
	context.subscriptions.push(disposable)
}
//该方法将在插件禁用的时候调用（目前是在插件卸载的时候触发）
function deactivate() {}
module.exports = {
	activate,
	deactivate
}
